home *** CD-ROM | disk | FTP | other *** search
- // ----------------------------------------------------------------------
- // 'extended' SHBrowseForFolder routine. ('New folder' button added)
- // Written by Xavier Roche, with the help of Gil Rosin,
- // Todd Fast's routines from Pencilneck Software and other Usenet contributors.
- // Freeware, but no warranty!
- //
- // Usage: (example)
- // CString path = XSHBrowseForFolder(this->m_hWnd,"Select path","c:\\") {
- //
- // To DO:
- //
- // #include "XSHBrowseForFolder.h"
- //
- // Then Add to the .rc file:
- //
- // IDD_NewFolder DIALOG DISCARDABLE 0, 0, 237, 46
- // STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
- // CAPTION "Create New Folder"
- // FONT 8, "MS Sans Serif"
- // BEGIN
- // EDITTEXT IDC_Folder,7,7,167,14,ES_AUTOHSCROLL
- // DEFPUSHBUTTON "OK",IDOK,180,7,50,14
- // PUSHBUTTON "Cancel",IDCANCEL,180,24,50,14
- // END
- // ----------------------------------------------------------------------
-
- // TODO: Put in XSHBrowseForFolder.h your ressource definition
-
- #include "stdafx.h"
- #include "shlobj.h"
- #include "XSHBrowseForFolder.h"
-
- // our button ID
- int XSHBFF_button1 = -1;
-
- // Main routine
- CString XSHBrowseForFolder(HWND hwnd,char* title,char* _path) {
- char path[MAX_PATH]; path[0]='\0';
-
- // Remove the last slash bar
- if (strlen(_path)>0)
- if (_path[strlen(_path)-1]=='\\')
- _path[strlen(_path)-1]='\0';
-
- // Get IMalloc Interface
- LPMALLOC Mymal;
- if (SHGetMalloc(&Mymal)!=NOERROR)
- return path;
-
- // Build Root directory (My Computer)
- LPITEMIDLIST Mylist;
- if (SHGetSpecialFolderLocation(hwnd,CSIDL_DRIVES,&Mylist)==NOERROR) {
-
- // Convert _path into browse data
- LPITEMIDLIST MyItemlist=XSHBFF_PathConvert(hwnd,_path);
-
- // Parameter structure for callback
- char Thispath[MAX_PATH]; Thispath[0]='\0';
- LONG CParam[2];
- CParam[0]=(LONG) MyItemlist;
- CParam[1]=(LONG) Thispath;
- // Fill the BROWSEINFO structure
- BROWSEINFO br;
- br.hwndOwner=hwnd; // hwnd
- br.pidlRoot=NULL; // root
- br.pszDisplayName=path; // buffer
- br.lpszTitle=title; // title
- br.ulFlags=BIF_RETURNONLYFSDIRS; // dir
- br.lpfn=XSHBFF_CallbackProc; // callback
- br.lParam=(LONG) CParam; // callback params
- br.iImage=0; // image
- // And Call SHBrowseForFolder
- LPITEMIDLIST UserList;
- if ( (UserList = SHBrowseForFolder(&br)) != NULL) {
- if (strlen(Thispath)==0) { // No value in path
- // Convert UserList to a string
- if (SHGetPathFromIDList(UserList,path)==FALSE)
- path[0]='\0';
- } else
- strcpy(path,Thispath);
- Mymal->Free(UserList);
- }
- if (MyItemlist) Mymal->Free(MyItemlist);
- Mymal->Free(Mylist);
- }
- return path;
- }
-
- // XSHBFF_WndProc function type
- typedef long (__stdcall * XSHBFF_WndProc_type)(HWND ,UINT ,WPARAM ,LPARAM);
-
- // Window Routine
- long __stdcall XSHBFF_WndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam) {
- static char StringSelection[MAX_PATH]="";
- static char* DirectReturnValue=NULL;
- static XSHBFF_WndProc_type Ladr=DefDlgProc;
- int wNotifyCode = HIWORD(wParam); // notification code
- int wID = LOWORD(wParam); // item, control, or accelerator identifier
- HWND hwndCtl = (HWND) lParam; // handle of control
- //
- if (uMsg==WM_COMMAND) { // WM_COMMAND message received
- if (wID == XSHBFF_button1 ) { // our button!
- if (strlen(StringSelection)>0) { // there is a selection
- CNewFolder f;
- f.m_folder=StringSelection;
- if (StringSelection[strlen(StringSelection)-1]!='\\')
- f.m_folder+="\\"; // add a /
- if (f.DoModal()==IDOK) {
- char st[MAX_PATH];
- strcpy(st,f.m_folder);
- // Remove the last slash bar
- if (strlen(st)>0)
- if (st[strlen(st)-1]=='\\')
- st[strlen(st)-1]='\0';
- // create dir
- if (_mkdir(st)) // error
- AfxMessageBox("Folder already exists, or can not be created",MB_OK+MB_ICONEXCLAMATION);
- else { // Select the new path
- if (DirectReturnValue) {
- strcpy(DirectReturnValue,st);
- wParam = (wParam & 0xFFFF0000) | XSHBrowseForFolder_OK; // 'OK'
- return Ladr(hwnd,uMsg,wParam,lParam); // former window routine
- }
- }
- }
- } else
- AfxMessageBox("Please select a path first!",MB_OK);
- return 0;
- } else {
- return Ladr(hwnd,uMsg,wParam,lParam); // former window routine
- }
- } else if (uMsg==XSHBrowseForFolder_SETSTRING) { // received from our XSHBFF_CallbackProc routine
- DirectReturnValue=(char*) lParam;
- return 0;
- } else if (uMsg==XSHBrowseForFolder_SETSTRING+1) {
- Ladr = (XSHBFF_WndProc_type) lParam; // store former address
- return 0;
- } else if (uMsg==BFFM_SELCHANGED) { // received from our XSHBFF_CallbackProc routine
- LPITEMIDLIST ItemSelection=(LPITEMIDLIST) lParam; // catch the Item selection data
- if (ItemSelection) { // valid data (not null)
- if (!SHGetPathFromIDList(ItemSelection,StringSelection)) { // immedialtly converted into char string
- StringSelection[0]='\0'; // clear, invalid
- }
- } else
- StringSelection[0]='\0'; // clear, invalid
- return 0;
- } else {
- return Ladr(hwnd,uMsg,wParam,lParam); // former window routine
- }
- }
-
- // Callback function
- int __stdcall XSHBFF_CallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData) {
- if (uMsg==BFFM_SELCHANGED) { // selection changed
- XSHBFF_WndProc(hwnd,BFFM_SELCHANGED,0,lParam);
- }
- else if (uMsg==BFFM_INITIALIZED) { // init
- // DO NOT ADD BUTTON
- #if 0000
- int x,y,w=0,h=0;
- HWND ok = GetDlgItem(hwnd,XSHBrowseForFolder_OK); // 'OK' button
- if (ok) {
- RECT rect;
- GetWindowRect(ok,&rect);
-
- // screen coord -> client coord
- POINT a,b;
- a.x=rect.left; a.y=rect.top; b.x=rect.right; b.y=rect.bottom;
- ScreenToClient(hwnd,&a); ScreenToClient(hwnd,&b);
- rect.left=a.x; rect.top=a.y; rect.right=b.x; rect.bottom=b.y;
-
- // button's coordinates and size
- x=rect.left;
- y=rect.top;
- w=rect.right-rect.left+1;
- h=rect.bottom-rect.top+1;
- x-=w+10; // nice shift
-
- // Okay, then create the button
- if (w*h != 0) {
- // button's styles
- int style = WS_CHILD | WS_CLIPSIBLINGS | BS_PUSHBUTTON | WS_TABSTOP | WS_VISIBLE;
- // create button, parent=hwnd
- HWND b = CreateWindow("BUTTON","New folder",style,x,y,w,h,hwnd,NULL,0,NULL);
- LONG Ladr=NULL;
- if (b!=NULL) {
- // Send Font notification so that the font be the same as default font
- HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
- ::SendMessage(b, WM_SETFONT, (WPARAM) hFont, MAKELPARAM(1,0));
- // Enable input
- EnableWindow(b,true);
- // Get the control ID of our button
- XSHBFF_button1 = GetDlgCtrlID(b);
- // Place our function
- Ladr = SetWindowLong(hwnd,GWL_WNDPROC,(LONG) XSHBFF_WndProc);
- }
-
- // initial selection
- LONG* Param = (LONG*) lpData;
- if (Param) {
- // Send init dir
- SendMessage(hwnd,BFFM_SETSELECTION,WPARAM(false),Param[0]); // init dir
- // Send string return address
- XSHBFF_WndProc(hwnd,XSHBrowseForFolder_SETSTRING,0,Param[1]); // return string
- // Send former function address
- if (Ladr) {
- XSHBFF_WndProc(hwnd,XSHBrowseForFolder_SETSTRING+1,0,Ladr); // return string
- }
- }
- }
- }
- #endif
- }
- return 0;
- }
-
- // Convert a char* into a LPITEMIDLIST
- LPITEMIDLIST XSHBFF_PathConvert(HWND hwnd,char* _path) {
- // Retrieves the IShellFolder interface for the desktop folder
- LPSHELLFOLDER MyShellFolder;
- if (SHGetDesktopFolder(&MyShellFolder) != NO_ERROR)
- return NULL;
-
- // Initial path
- ULONG pchEaten;
- LPITEMIDLIST MyItemlist=NULL;
- ULONG pdwAttributes;
- if (strlen(_path)>0) {
- char* lpszA = _path;
- // -- Unicode conversion--
- // we want to convert an MBCS string into lpszA
- int nLen = MultiByteToWideChar(CP_ACP, 0,lpszA, -1, NULL, NULL);
- LPWSTR lpszW = new WCHAR[nLen];
- MultiByteToWideChar(CP_ACP, 0, lpszA, -1, lpszW, nLen);
- // parse string
- MyShellFolder->ParseDisplayName(hwnd,NULL,lpszW,&pchEaten,&MyItemlist,&pdwAttributes);
- // free the string
- delete[] lpszW;
- // -- Unicode conversion--
- }
- return MyItemlist;
- }
-
- // ----------------------------------------------------------------------
- // 'extended' SHBrowseForFolder routine. 'New folder' button added.
- // ----------------------------------------------------------------------
-
-